#!/usr/ali/bin/python
# coding=utf-8

'''A simple interface to execute shell commands.

These ideas are taken from fabric/operations.py.

See test_main() for mor examples.
'''

# Can be 'Prototype', 'Development', 'Product'
__status__ = 'Development'

import subprocess
from threading import Timer

from pypet.common.storage import Storage

def remote(addr, cmd, timeout = None):
    '''Run command on remote host through ssh.

    addr is the remote host address, which can be hostname or ip address.
    cmd can be any shell commands, which will be run in remote host through
    ssh protocol.

    If timeout is not None, the running command will quit in timeout seconds.
    '''
    ssh = "ssh -o StrictHostKeyChecking=no -o LogLevel=quiet -o BatchMode=yes"

    if timeout is not None:
        ssh += ' -o ConnectTimeout=%d' % timeout

    cmd = '%s %s "%s"' % (ssh, addr, cmd)

    return local(cmd)

def remote_copy(addr, src, dst, timeout = 0):
    '''Copy file from src to dst on remote host through scp.
       
    addr is the remote host address, which can be hostname or ip address.
    src and dest are the source and the destination when copy. 

    If timeout is not 0, the running command will quit in timeout seconds.
    '''
    scp = "scp -o StrictHostKeyChecking=no -o LogLevel=quiet -o BatchMode=yes"

    if isinstance(timeout, int) and timeout > 0:
        scp += ' -o ConnectTimeout=%d' % timeout

    cmd = '%s %s %s:%s' % (scp, src, addr, dst)

    return local(cmd)

def local(cmd, shell = None):
    '''Run command in local host.
       
    cmd can be any shell commands, which will be run in remote host through

    By default, this function use '/bin/sh' to run command, you can specify
    another shell through the shell argument if need.
    '''
    p = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE,
            stderr = subprocess.PIPE, executable = shell)
    stdout, stderr = p.communicate()

    out = Storage()

    out.stdout = stdout.strip() if stdout else ""
    out.stderr = stderr.strip() if stderr else ""

    out.cmd = cmd
    out.failed = False
    out.return_code = p.returncode

    if p.returncode != 0:
        out.failed = True

    out.succeeded = not out.failed

    return out

def test_main():
    '''Test main entry.'''
    # Run local command
    out = local('uname -r')

    if out.succeeded:
        print "stdout:", out.stdout
    else:
        print "stderr: %s", out.stderr

    # Execute command in remote host through ssh
    out = remote('houyi-vm07.dev.sd.aliyun.com', 'uname -r')

    if out.succeeded:
        print "stdout:", out.stdout
    else:
        print "stderr:", out.stderr

    # Copy file from local to remote through scp
    host = 'houyi-vm07.dev.sd.aliyun.com'
    out = remote_copy(host, '/var/log/messages', '/tmp')

    if out.succeeded:
        print "stdout:", out.stdout
    else:
        print "stderr:", out.stderr

if __name__ == '__main__':
    test_main()
